const express = require('express');
const cors = require('cors');
const fs = require('fs').promises;
const path = require('path');
const crypto = require('crypto');
const app = express();

// 中间件
app.use(cors());
app.use(express.json());

// 导入路由
const zkRouter = require('./routes/zk');

// 挂载路由
app.use('/api', zkRouter);

// 确保数据目录存在
const dataDir = path.join(__dirname, 'data');
fs.mkdir(dataDir, { recursive: true }).catch(console.error);

// 文件路径
const usersPath = path.join(__dirname, '../data/users.json');
const transactionsPath = path.join(__dirname, '../data/transactions.json');

// 读取JSON文件
const readJsonFile = async (filename) => {
  try {
    const filePath = path.join(__dirname, 'data', filename);
    console.log('Reading file:', filePath);
    const data = await fs.readFile(filePath, 'utf8');
    console.log('File content:', data);

    // 确保数据是有效的JSON
    let parsed;
    try {
      parsed = JSON.parse(data);
    } catch (parseError) {
      console.error('JSON parse error:', parseError);
      return [];
    }

    // 确保数据是数组
    if (!Array.isArray(parsed)) {
      console.error('Data is not an array:', parsed);
      return [];
    }

    console.log('Parsed data:', parsed);
    return parsed;
  } catch (error) {
    console.error('Error reading file:', error);
    if (error.code === 'ENOENT') {
      // 如果文件不存在，返回空数组
      return [];
    }
    throw error;
  }
};

// 写入JSON文件
const writeJsonFile = async (filename, data) => {
  try {
    const filePath = path.join(__dirname, 'data', filename);
    console.log('Writing to file:', filePath);
    console.log('Data to write:', data);
    await fs.writeFile(filePath, JSON.stringify(data, null, 2));
  } catch (error) {
    console.error('Error writing file:', error);
    throw error;
  }
};

// 信用评分规则
const CREDIT_RULES = {
  MIN_SCORE: 600,
  MAX_SCORE: 850,
  LOAN_LIMITS: {
    600: 1000,    // 600分可借1000
    650: 2000,    // 650分可借2000
    700: 5000,    // 700分可借5000
    750: 10000,   // 750分可借10000
    800: 20000,   // 800分可借20000
    850: 50000    // 850分可借50000
  },
  SCORE_CHANGES: {
    ON_TIME_REPAYMENT: 10,    // 按时还款加10分
    LATE_REPAYMENT_1: -20,    // 逾期1-7天扣20分
    LATE_REPAYMENT_2: -50,    // 逾期8-30天扣50分
    LATE_REPAYMENT_3: -100    // 逾期30天以上扣100分
  }
};

// 计算用户行为评分
const calculateBehaviorScore = (user, transactions) => {
  let score = 600; // 基础分
  const userTransactions = transactions.filter(t =>
    t.fromUserId === user.id || t.toUserId === user.id
  );

  // 分析交易历史
  userTransactions.forEach(transaction => {
    if (transaction.type === 'loan') {
      if (transaction.status === 'completed') {
        // 按时还款加分
        const dueDate = new Date(transaction.dueDate);
        const repaidAt = new Date(transaction.repaidAt);
        const daysLate = Math.floor((repaidAt - dueDate) / (24 * 60 * 60 * 1000));

        if (daysLate <= 0) {
          score += 10; // 按时还款
        } else if (daysLate <= 7) {
          score += 5; // 轻微逾期
        } else if (daysLate <= 30) {
          score -= 10; // 中度逾期
        } else {
          score -= 30; // 严重逾期
        }
      } else if (transaction.status === 'pending') {
        // 有未还款记录，降低评分
        score -= 20;
      }
    }
  });

  // 确保分数在合理范围内
  return Math.max(CREDIT_RULES.MIN_SCORE, Math.min(CREDIT_RULES.MAX_SCORE, score));
};

// 生成信用证明
app.post('/api/generate-credit-proof', async (req, res) => {
  try {
    const { userId, creditScore } = req.body;

    // 生成唯一的证明ID
    const proofId = crypto.randomBytes(16).toString('hex');

    // 生成验证码
    const verificationCode = crypto.randomBytes(8).toString('hex');

    const proof = {
      id: proofId,
      userId,
      creditScore,
      verificationCode,
      timestamp: Date.now(),
      expiresAt: Date.now() + 24 * 60 * 60 * 1000 // 24小时后过期
    };

    // 读取现有的证明记录
    const proofs = await readJsonFile('credit_proofs.json');

    // 添加新证明
    proofs.push(proof);

    // 保存更新后的证明记录
    await writeJsonFile('credit_proofs.json', proofs);

    res.json({
      success: true,
      proof: {
        id: proof.id,
        timestamp: proof.timestamp,
        expiresAt: proof.expiresAt,
        verificationCode: proof.verificationCode
      }
    });
  } catch (error) {
    console.error('生成信用证明失败:', error);
    res.status(500).json({
      success: false,
      message: '生成信用证明失败'
    });
  }
});

// 验证信用证明
app.post('/api/verify-credit-proof', async (req, res) => {
  try {
    const { proof, verificationCode } = req.body;

    // 读取证明记录
    const proofs = await readJsonFile('credit_proofs.json');

    // 查找匹配的证明
    const matchingProof = proofs.find(p =>
      p.id === proof.id &&
      p.verificationCode === verificationCode &&
      p.expiresAt > Date.now()
    );

    if (!matchingProof) {
      return res.status(400).json({
        success: false,
        message: '无效的信用证明或验证码'
      });
    }

    res.json({
      success: true,
      message: '信用证明验证成功',
      creditScore: matchingProof.creditScore
    });
  } catch (error) {
    console.error('验证信用证明失败:', error);
    res.status(500).json({
      success: false,
      message: '验证信用证明失败'
    });
  }
});

// 更新用户信用分
const updateUserCreditScore = (user, change, reason) => {
  const newScore = Math.max(
    CREDIT_RULES.MIN_SCORE,
    Math.min(CREDIT_RULES.MAX_SCORE, user.creditScore + change)
  );

  user.creditScore = newScore;
  user.creditHistory.push({
    timestamp: new Date().toISOString(),
    type: 'change',
    score: newScore,
    change,
    description: reason
  });
};

// 获取可借款额度
const getLoanLimit = (creditScore) => {
  const scores = Object.keys(CREDIT_RULES.LOAN_LIMITS)
    .map(Number)
    .sort((a, b) => a - b);

  for (let i = scores.length - 1; i >= 0; i--) {
    if (creditScore >= scores[i]) {
      return CREDIT_RULES.LOAN_LIMITS[scores[i]];
    }
  }
  return 0;
};

// 身份验证API
app.post('/api/login', async (req, res) => {
  try {
    const { username, password } = req.body;
    console.log('Login attempt:', { username, password });

    // 读取用户数据
    let users;
    try {
      users = await readJsonFile('users.json');
      console.log('Users data:', users);
    } catch (error) {
      console.error('Error reading users file:', error);
      return res.status(500).json({
        success: false,
        message: '读取用户数据失败'
      });
    }

    // 确保users是数组
    if (!Array.isArray(users)) {
      console.error('Users data is not an array:', users);
      return res.status(500).json({
        success: false,
        message: '用户数据格式错误'
      });
    }

    // 查找用户
    const user = users.find(u => u.username === username && u.password === password);
    console.log('Found user:', user);

    if (!user) {
      return res.status(401).json({
        success: false,
        message: '用户名或密码错误'
      });
    }

    res.json({
      success: true,
      user: {
        id: user.id,
        username: user.username,
        creditScore: user.creditScore
      }
    });
  } catch (error) {
    console.error('登录失败:', error);
    res.status(500).json({
      success: false,
      message: '登录失败'
    });
  }
});

// 获取用户信息API
app.get('/api/user/:id', async (req, res) => {
  try {
    const { id } = req.params;
    console.log('Getting user info for ID:', id);

    // 读取用户数据
    let users;
    try {
      users = await readJsonFile('users.json');
      console.log('Users data:', users);
    } catch (error) {
      console.error('Error reading users file:', error);
      return res.status(500).json({
        success: false,
        message: '读取用户数据失败'
      });
    }

    // 确保users是数组
    if (!Array.isArray(users)) {
      console.error('Users data is not an array:', users);
      return res.status(500).json({
        success: false,
        message: '用户数据格式错误'
      });
    }

    // 查找用户
    const user = users.find(u => u.id === parseInt(id));
    console.log('Found user:', user);

    if (!user) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    res.json({
      success: true,
      user: {
        id: user.id,
        username: user.username,
        creditScore: user.creditScore,
        balance: user.balance || 0
      }
    });
  } catch (error) {
    console.error('获取用户信息失败:', error);
    res.status(500).json({
      success: false,
      message: '获取用户信息失败'
    });
  }
});

// 借款API
app.post('/api/borrow', async (req, res) => {
  try {
    const { userId, amount, creditProof, verificationCode } = req.body;
    console.log('Borrow request:', { userId, amount, creditProof, verificationCode });

    // 验证请求参数
    if (!userId || !amount || !creditProof || !verificationCode) {
      console.error('Missing required parameters:', { userId, amount, creditProof, verificationCode });
      return res.status(400).json({
        success: false,
        message: '缺少必要的参数'
      });
    }

    // 验证creditProof格式
    if (!creditProof.id) {
      console.error('Invalid credit proof format:', creditProof);
      return res.status(400).json({
        success: false,
        message: '信用证明格式无效'
      });
    }

    // 读取用户数据
    const users = await readJsonFile('users.json');
    console.log('Users data:', users);

    // 读取交易数据
    const transactions = await readJsonFile('transactions.json');
    console.log('Transactions data:', transactions);

    const user = users.find(u => u.id === parseInt(userId));
    if (!user) {
      console.error('User not found:', userId);
      return res.status(404).json({ success: false, message: '用户不存在' });
    }

    // 验证信用证明和口令
    const proofs = await readJsonFile('credit_proofs.json');
    console.log('Credit proofs:', proofs);

    const matchingProof = proofs.find(p =>
      p.id === creditProof.id &&
      p.verificationCode === verificationCode &&
      p.expiresAt > Date.now()
    );

    if (!matchingProof) {
      console.error('Invalid credit proof or verification code:', {
        proofId: creditProof.id,
        verificationCode,
        availableProofs: proofs.map(p => ({ id: p.id, expiresAt: p.expiresAt }))
      });
      return res.status(400).json({
        success: false,
        message: '信用证明或验证口令无效'
      });
    }

    // 检查借款额度
    const loanLimit = getLoanLimit(matchingProof.creditScore);
    console.log('Loan limit check:', {
      creditScore: matchingProof.creditScore,
      requestedAmount: amount,
      loanLimit
    });

    if (amount > loanLimit) {
      return res.status(400).json({
        success: false,
        message: `借款金额超过限额，当前信用分${matchingProof.creditScore}可借${loanLimit}`
      });
    }

    // 记录借款
    const newTransaction = {
      id: transactions.length + 1,
      fromUserId: 2, // 系统账户
      toUserId: parseInt(userId),
      amount: parseInt(amount),
      timestamp: new Date().toISOString(),
      type: 'loan',
      status: 'pending',
      creditProof: matchingProof,
      dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString() // 30天后到期
    };

    console.log('Creating new transaction:', newTransaction);

    transactions.push(newTransaction);
    user.loanHistory.push(newTransaction.id);

    // 更新余额
    user.balance += parseInt(amount);
    console.log('Updated user balance:', {
      userId: user.id,
      newBalance: user.balance
    });

    // 保存更新
    await writeJsonFile('users.json', users);
    await writeJsonFile('transactions.json', transactions);

    res.json({
      success: true,
      message: '借款成功',
      transaction: newTransaction
    });
  } catch (error) {
    console.error('借款失败:', error);
    res.status(500).json({
      success: false,
      message: '借款失败'
    });
  }
});

// 还款API
app.post('/api/repay', async (req, res) => {
  try {
    const { userId, transactionId } = req.body;
    console.log('Repay request:', { userId, transactionId });

    // 读取用户数据
    const users = await readJsonFile('users.json');
    console.log('Users data:', users);

    // 读取交易数据
    const transactions = await readJsonFile('transactions.json');
    console.log('Transactions data:', transactions);

    const user = users.find(u => u.id === parseInt(userId));
    const transaction = transactions.find(t => t.id === parseInt(transactionId));

    if (!user || !transaction) {
      console.error('User or transaction not found:', { userId, transactionId });
      return res.status(404).json({
        success: false,
        message: '用户或交易不存在'
      });
    }

    if (transaction.type !== 'loan' || transaction.status !== 'pending') {
      console.error('Invalid repayment request:', transaction);
      return res.status(400).json({
        success: false,
        message: '无效的还款请求'
      });
    }

    // 检查余额
    if (user.balance < transaction.amount) {
      console.error('Insufficient balance:', {
        balance: user.balance,
        required: transaction.amount
      });
      return res.status(400).json({
        success: false,
        message: '余额不足'
      });
    }

    // 更新交易状态
    transaction.status = 'completed';
    transaction.repaidAt = new Date().toISOString();

    // 更新余额
    user.balance -= transaction.amount;

    // 更新信用分
    const dueDate = new Date(transaction.dueDate);
    const repaidAt = new Date(transaction.repaidAt);
    const daysLate = Math.floor((repaidAt - dueDate) / (24 * 60 * 60 * 1000));

    let scoreChange = CREDIT_RULES.SCORE_CHANGES.ON_TIME_REPAYMENT;
    let reason = '按时还款';

    if (daysLate > 0) {
      if (daysLate <= 7) {
        scoreChange = CREDIT_RULES.SCORE_CHANGES.LATE_REPAYMENT_1;
        reason = '逾期1-7天';
      } else if (daysLate <= 30) {
        scoreChange = CREDIT_RULES.SCORE_CHANGES.LATE_REPAYMENT_2;
        reason = '逾期8-30天';
      } else {
        scoreChange = CREDIT_RULES.SCORE_CHANGES.LATE_REPAYMENT_3;
        reason = '逾期30天以上';
      }
    }

    // 更新用户信用分
    const newScore = Math.max(
      CREDIT_RULES.MIN_SCORE,
      Math.min(CREDIT_RULES.MAX_SCORE, user.creditScore + scoreChange)
    );

    user.creditScore = newScore;
    user.creditHistory.push({
      timestamp: new Date().toISOString(),
      type: 'change',
      score: newScore,
      change: scoreChange,
      description: reason
    });

    // 保存更新
    await writeJsonFile('users.json', users);
    await writeJsonFile('transactions.json', transactions);

    console.log('Repayment successful:', {
      userId,
      transactionId,
      newBalance: user.balance,
      newScore: user.creditScore
    });

    res.json({
      success: true,
      message: '还款成功',
      creditScore: user.creditScore,
      scoreChange,
      newBalance: user.balance
    });
  } catch (error) {
    console.error('还款失败:', error);
    res.status(500).json({
      success: false,
      message: '还款失败'
    });
  }
});

// 获取交易历史API
app.get('/api/transactions/:userId', async (req, res) => {
  try {
    const { userId } = req.params;
    const transactions = await readJsonFile('transactions.json');

    if (!Array.isArray(transactions)) {
      throw new Error('交易数据格式错误');
    }

    const userTransactions = transactions.filter(
      t => t.fromUserId === parseInt(userId) || t.toUserId === parseInt(userId)
    );

    res.json({
      success: true,
      transactions: userTransactions
    });
  } catch (error) {
    console.error('获取交易历史失败:', error);
    res.status(500).json({
      success: false,
      message: '获取交易历史失败'
    });
  }
});

// 获取信用历史API
app.get('/api/credit-history/:userId', async (req, res) => {
  try {
    const { userId } = req.params;
    const users = await readJsonFile('users.json');

    if (!Array.isArray(users)) {
      throw new Error('用户数据格式错误');
    }

    const user = users.find(u => u.id === parseInt(userId));

    if (!user) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    res.json({
      success: true,
      creditHistory: user.creditHistory || []
    });
  } catch (error) {
    console.error('获取信用历史失败:', error);
    res.status(500).json({
      success: false,
      message: '获取信用历史失败'
    });
  }
});

// 获取用户最新的信用证明
app.get('/api/credit-proofs/:userId/latest', async (req, res) => {
  try {
    const { userId } = req.params;
    console.log('Getting latest credit proof for user:', userId);

    // 读取信用证明数据
    const proofs = await readJsonFile('credit_proofs.json');
    console.log('All credit proofs:', proofs);

    // 找到用户最新的有效信用证明
    const latestProof = proofs
      .filter(p => p.userId === parseInt(userId) && p.expiresAt > Date.now())
      .sort((a, b) => b.timestamp - a.timestamp)[0];

    if (!latestProof) {
      return res.status(404).json({
        success: false,
        message: '未找到有效的信用证明'
      });
    }

    res.json({
      success: true,
      proof: latestProof
    });
  } catch (error) {
    console.error('获取信用证明失败:', error);
    res.status(500).json({
      success: false,
      message: '获取信用证明失败'
    });
  }
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
}); 